package cn.doitedu.demo10.web_test;

import org.junit.Test;
import org.roaringbitmap.longlong.Roaring64Bitmap;
import redis.clients.jedis.Jedis;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class RuleInjectWebTest {

    @Test
    public void ruleMode1() throws Exception {

        Connection connection = DriverManager.getConnection("jdbc:mysql://doitedu:3306/doit41", "root", "root");
        PreparedStatement stmt = connection.prepareStatement("insert into rule_meta values(?,?,?,?,?,?)");
        stmt.setString(1, "rule-1-002");
        stmt.setString(2, "model-1");
        stmt.setString(3, "{\"rule_id\":\"rule-1-002\",\"event_id\":\"M\"}");
        stmt.setInt(4, 1);

        // 去es中根据上面的规则参数中的静态画像条件查询满足的人群
        Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf(1, 3, 4, 5, 7, 8);
        // 将bitmap序列化
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(bout);
        bitmap.serialize(dout);
        byte[] bitMapBytes = bout.toByteArray();

        stmt.setBytes(5, bitMapBytes);


        // 去规则模型运算机代码表中，查询该规则对应的模型的代码
        PreparedStatement stmt2 = connection.prepareStatement("select  model_calculator_code  from model_calculator where model_id = ?");
        stmt2.setString(1, "model-1");
        ResultSet resultSet = stmt2.executeQuery();
        resultSet.next();
        String calculatorCode = resultSet.getString("model_calculator_code");

        // 将代码设置到插入语句的参数中
        stmt.setString(6, calculatorCode);

        // 执行insert语句
        stmt.execute();

    }


    @Test
    public void ruleMode2() throws Exception {

        Connection connection = DriverManager.getConnection("jdbc:mysql://doitedu:3306/doit41", "root", "root");
        PreparedStatement stmt = connection.prepareStatement("insert into rule_meta values(?,?,?,?,?,?)");
        stmt.setString(1, "rule-2-001");
        stmt.setString(2, "model-2");
        stmt.setString(3, "{\"rule_id\":\"rule-2-001\",\"profile_conditions\":[{\"tag_name\":\"gender\",\"compare_type\":\"=\",\"condition_values\":[\"female\"]}],\"realtime_profile\":{\"event_id\":\"P\",\"min_count\":2},\"fire_condition\":{\"event_id\":\"G\"}}");
        stmt.setInt(4, 1);

        // 去es中根据上面的规则参数中的静态画像条件查询满足的人群
        Roaring64Bitmap bitmap = Roaring64Bitmap.bitmapOf(10, 13, 24, 55, 67, 86, 100);
        // 将bitmap序列化
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(bout);
        bitmap.serialize(dout);
        byte[] bitMapBytes = bout.toByteArray();

        stmt.setBytes(5, bitMapBytes);


        // 查询出该规则的模型运算机代码
        PreparedStatement stmt2 = connection.prepareStatement("select  model_calculator_code  from model_calculator where model_id = ?");
        stmt2.setString(1, "model-2");
        ResultSet resultSet = stmt2.executeQuery();
        resultSet.next();
        String calculatorCode = resultSet.getString("model_calculator_code");

        // 将代码设置到插入语句的参数中
        stmt.setString(6, calculatorCode);


        // 执行insert语句
        stmt.execute();

    }


    @Test
    public void ruleMode3() throws Exception {
        /**
         * 创建redis客户端连接
         */
        Jedis jedis = new Jedis("doitedu", 6379);


        /**
         * 去es中根据静态画像条件预圈选人群
         */
        Roaring64Bitmap preSelectUsersBitmap = Roaring64Bitmap.bitmapOf(1, 2, 3, 4, 5, 8, 9);


        /**
         * 先去doris中统计动态画像条件的历史值
         */
        // 目标事件： w,  统计区间： 2023-07-01  =>  未来
        Connection dorisConnection = DriverManager.getConnection("jdbc:mysql://doitedu:9030/test", "root", "root");
        String sql =
                "select  " +
                        "      user_id, " +
                        "      count(1) as event_cnt  " +
                        "  from test.user_events  " +
                        "  where event_id = ?  " +
                        "  and event_time between ? and ?  " +
                        "  group by user_id";

        PreparedStatement dorisStmt = dorisConnection.prepareStatement(sql);
        dorisStmt.setString(1, "w");
        dorisStmt.setLong(2, 1689302028000L);

        long webCalcEndTime = System.currentTimeMillis();
        dorisStmt.setLong(3, webCalcEndTime);
        // 执行查询
        ResultSet dorisResultSet = dorisStmt.executeQuery();
        while (dorisResultSet.next()) {
            long userId = dorisResultSet.getLong("user_id");
            int eventCnt = dorisResultSet.getInt("event_cnt");
            // 将历史值发布到redis
            if(preSelectUsersBitmap.contains(userId)){
                jedis.hset("rule-3-001:1",userId+"",eventCnt+"");
            }
        }



        /**
         * 往mysql写规则元数据
         */
        Connection connection = DriverManager.getConnection("jdbc:mysql://doitedu:3306/doit41", "root", "root");
        PreparedStatement stmt = connection.prepareStatement("insert into rule_meta values(?,?,?,?,?,?,?)");
        stmt.setString(1, "rule-3-001");
        stmt.setString(2, "model-3");
        stmt.setString(3, "{\n" +
                "  \"rule_id\":\"rule-3-001\",\n" +
                "  \"profile_condition\":{\n" +
                "    \"tag_name\":\"age\",\n" +
                "    \"tag_value\":30\n" +
                "  },\n" +
                "  \"realtime_profile\":[\n" +
                "    {\n" +
                "      \"start_time\":\"2023-09-01 08:00:00\",\n" +
                "      \"end_time\": \"2023-10-20 23:00:00\",\n" +
                "      \"event_id\": \"w\",\n" +
                "      \"min_count\": 3,\n" +
                "      \"rp_condition_id\":1\n" +
                "    },\n" +
                "    {\n" +
                "      \"start_time\":\"2023-09-11 08:00:00\",\n" +
                "      \"end_time\": \"\",\n" +
                "      \"event_id\": \"K\",\n" +
                "      \"min_count\": 5,\n" +
                "      \"rp_condition_id\":2\n" +
                "    }\n" +
                "  ],\n" +
                "  \"fire_event_id\":\"V\"\n" +
                "}");
        stmt.setInt(4, 1);

        // 去es中根据上面的规则参数中的静态画像条件查询满足的人群
        // 将bitmap序列化
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(bout);
        preSelectUsersBitmap.serialize(dout);
        byte[] bitMapBytes = bout.toByteArray();

        stmt.setBytes(5, bitMapBytes);


        // 查询出该规则的模型运算机代码
        PreparedStatement stmt2 = connection.prepareStatement("select  model_calculator_code  from model_calculator where model_id = ?");
        stmt2.setString(1, "model-3");
        ResultSet resultSet = stmt2.executeQuery();
        resultSet.next();
        String calculatorCode = resultSet.getString("model_calculator_code");

        // 将代码设置到插入语句的参数中
        stmt.setString(6, calculatorCode);


        // web端历史值统计截止时间点
        stmt.setLong(7,webCalcEndTime);

        // 执行insert语句
        stmt.execute();

    }


}
